"""
    @author    Thomas Lehmann
    @file      Limits.py
    @language  Please use python >= 3.2

    @note Using the tool against itself should never throw any warning or error!
    @note I don't use TAB's and indentation is 4.
    @note I'm using the documentation tool 'epydoc' (http://epydoc.sourceforge.net/)
          for generating HTML documentation of this.
"""

from GreenYellowRedLimit import GreenYellowRedLimit

class Limits:
    """ Does group all limits to be checked by this scripts """
    def __init__(self):
        """ initializes container for limit defintions only """
        self.definitions = {}

    def registerLimit(self, name, limit):
        """ registration of a limit
            @param name
                    name of the limit
            @param limit
                    instance of GreenYellowRedLimit class
        """
        if not name in self.definitions:
            self.definitions[name] = limit
        return limit

    def maxAttributesPerClass(self):
        """ <b>Too many attributes per class</b>:<br>
            Is an indicator for bad design. Maybe the class is too complex or an
            improper way to store information has been used. """
        return self.registerLimit(self.maxAttributesPerClass.__name__,
            GreenYellowRedLimit( 10,  15, "too many attributes in class"))

    def maxFunctionsPerClass(self):
        """ <b>Too many functions per class</b>:<br>
            Is an indicator for bad design. Maybe the class does handle too much. """
        return self.registerLimit(self.maxFunctionsPerClass.__name__,
            GreenYellowRedLimit( 20,  25, "too many functions in class"))

    def maxFunctionsPerFile(self):
        """ <b>Too many functions per file</b>:<br>
            Is an indicator for bad design. You have too many logic in one file.
            The different to many functions per class is that global functions are
            counted as well as functions of multiple classes in same file. """
        return self.registerLimit(self.maxFunctionsPerFile.__name__,
            GreenYellowRedLimit( 35,  40, "too many functions in file"))

    def maxClassesPerFile(self):
        """ <b>Too many classes per file</b>:<br>
            Is an indicator for bad design and/or simply the fact that the file
            could be splitted up for different classes. """
        return self.registerLimit(self.maxClassesPerFile.__name__,
            GreenYellowRedLimit(  4,   6, "too many classes in file"))

    def maxParametersPerFunction(self):
        """ <b>Too many parameters in function/method</b>:<br>
            Is an indicator for bad design. Are many of those parameters also required
            by other functions or methods? Can't you provide a class or a dictionary? """
        return self.registerLimit(self.maxParametersPerFunction.__name__,
            GreenYellowRedLimit(  4,   6, "too many parameters in function/method"))

    def maxLinesPerFunction(self):
        """ <b>Too many lines per function/method</b>:<br>
            The idea is to have - more or less - the content of the whole function
            or method visible on one screen to avoid scrolling. On Windows I have
            a "Courier New" font with size 10 and that's really not too big and not too
            small; with this I can see about 50 lines of code. With an output window or
            other information at the bottom (IDE) you will see less than this. This metric
            includes comments, excludes blank lines."""
        return self.registerLimit(self.maxLinesPerFunction.__name__,
            GreenYellowRedLimit( 50, 100, "too many lines in function/method"))

    def maxControlStatementsPerFunction(self):
        """ <b>Too many control statements</b>:<br>
            Is an indicator that the function/method is too complex. """
        return self.registerLimit(self.maxControlStatementsPerFunction.__name__,
            GreenYellowRedLimit( 15,  20, "too many control statements"))

    def maxCharactersPerLine(self):
        """ <b>Line too long</b>:<br>
            I want to see the whole line without scrolling. Another aspect of this
            is when you use tools for comparing two versions (side by side) or
            when printing it out; it's to avoid wrapping code into the next lines.
            <b>It's about readability!</b> """
        return self.registerLimit(self.maxCharactersPerLine.__name__,
            GreenYellowRedLimit( 95, 110, "line too long"))

    def maxLinesPerFile(self):
        """ <b>Too many lines in file</b>:<br>
            Is an indicator for bad design. I know from files with several thousand
            lines of code and especially those file mostly are difficult to maintain.
            This metric includes comments, excludes blank lines. """
        return self.registerLimit(self.maxLinesPerFile.__name__,
            GreenYellowRedLimit(550, 750, "too many lines in file"))

    def maxIndentationLevel(self):
        """ <b>Too many indentation levels</b>:<br>
            Is an indicator that the code is too complex! It's about examples like having
            an if statement containing an if statement and again containing an if
            statement and again ... """
        return self.registerLimit(self.maxIndentationLevel.__name__,
            GreenYellowRedLimit(  3,   5, "too many indentation levels"))

    def maxTabs(self):
        """ <b>Too many tabs</b>:<br>
            This a visual style issue. You can disallow tabs if wanted.
            Default: no tabs are allowed. """
        return self.registerLimit(self.maxTabs.__name__,
            GreenYellowRedLimit(  0,   0, "too many tabs"))

    def maxValueRepetition(self):
        """ <b>value used too often without name</b>:<br>
            Is an indicator for bad design. If a value change you might have
            to adjust code at all location where it is used. That's why
            you should defined constants and not values """
        return self.registerLimit(self.maxValueRepetition.__name__,
            GreenYellowRedLimit(  3,   5, "constant value used too often without name"))
